package com.zj.weather.bgviews;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;


import java.util.ArrayList;
import java.util.List;

import com.zj.weather.base.BaseHolder;
import com.zj.weather.base.BaseWeatherBgView;
import com.zj.weather.R;
import com.zj.weather.base.HoldersInfo;
import com.zj.weather.utils.StaticValue;

import static com.zj.weather.utils.RandomUtils.getRandom;
import static com.zj.weather.utils.StaticValue.getResId;

/**
 * Created by zhaojie on 2017/9/14.
 */
public class CloudyDrawer extends BaseWeatherBgView {

    private static final int maxCount = 5;

    public CloudyDrawer(Context context) {
        super(context);
    }

    @Override
    protected List<HoldersInfo> getHolders() {
        List<HoldersInfo> infos = new ArrayList<>();
        infos.add(new HoldersInfo(maxCount) {
            @Override
            public CloudHolder getHolderType(int position) {
                return new CloudHolder(width, height,position);
            }
        });
        return infos;
    }

    public static class CloudHolder extends BaseHolder {
        private float alpha, w, h, curOffset;
        private int cur_y;
        private CloudInfo cloudInfo;


        CloudHolder(int x, int y, int position) {
            super(x, y, position);
        }

        @Override
        public void initData(Context context) {
            this.curOffset = getRandom(-0.32f, 1.25f);
            updateParam(context);
        }

        @Override
        public void updateFrame(Context context, Canvas canvas, float changedAlpha) {
            curOffset += cloudInfo.speed;
            float curX = curOffset * canvasWidth - (w / 2f);
            int left = (int) ((canvasWidth - curX) - w / 2f);
            int right = (int) ((canvasWidth - curX) + w / 2f);
            int top = (int) (cur_y - h / 2f);
            int bottom = (int) (cur_y + h / 2f);
            Drawable cloud = cloudInfo.drawable;
            cloud.setBounds(left, top, right, bottom);
            cloud.setAlpha((int) (alpha * changedAlpha));
            cloud.draw(canvas);
            if (curX > (canvasWidth + w / 2f)) {
                curOffset = 0.0f;
                updateParam(context);
            }
        }

        private void updateParam(Context context) {
            int curResId = (int) (getRandom(0.0f, 1.0f) * 10f);
            cloudInfo = new CloudInfo(context, curResId);
            float offset = getRandom(0.61f, 0.75f);
            float scale = getRandom(0.4f, 0.45f);
            this.w = offset * canvasWidth;
            this.h = w * scale;
            this.cur_y = (int) (canvasHeight * cloudInfo.Offset_Y);
            float[] al = getCurAlpha();
            this.alpha = getRandom(al[0], al[1]) * 255f;
        }

        private float[] getCurAlpha() {
            float[] alpha = new float[2];
            if (StaticValue.isDay()) {
                alpha[0] = 0.65f;
                alpha[1] = 0.78f;
            } else {
                alpha[0] = 0.25f;
                alpha[1] = 0.42f;
            }
            return alpha;
        }

        private static class CloudInfo {

            public Drawable drawable;
            public float speed;
            public float Offset_Y;

            public CloudInfo(Context context, int curResId) {
                int resId = (curResId % 3 + 1);
                this.drawable = getDrawable(context, resId);
                this.speed = getSpeed(resId);
                Offset_Y = getYOffset(resId);
            }

            private Drawable getDrawable(Context context, int id) {
                return context.getResources().getDrawable(getResId(("cloud_" + id), R.mipmap.class));
            }

            private float getSpeed(int id) {
                float minX = 0.0006f, maxX = 0.0013f;
                switch (id) {
                    case 1:
                        minX = 0.0008f;
                        maxX = 0.0011f;
                        break;
                    case 2:
                        minX = 0.0007f;
                        maxX = 0.0010f;
                        break;
                    case 3:
                        minX = 0.0003f;
                        maxX = 0.0006f;
                        break;
                }
                return getRandom(minX, maxX);
            }

            private float getYOffset(int id) {
                float y1 = 0.07f, y2 = 0.33f;
                switch (id) {
                    case 1:
                        y1 = 0.13f;
                        y2 = 0.16f;
                        break;
                    case 2:
                        y1 = 0.17f;
                        y2 = 0.21f;
                        break;
                    case 3:
                        y1 = 0.22f;
                        y2 = 0.27f;
                        break;
                }
                return getRandom(y1, y2);
            }

        }

    }
}

